﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HidesaburoDotNET.Core.Detecctors
{
    public class DetectingMediator
    {
        public DetectingMediator() {
            Initialize();
        }

        public List<Yaku> Detect(AgariTehai tehai)
        {
            List<Yaku> yakuList = new List<Yaku>();

            TanyaoDetector detector = new TanyaoDetector();
            Yaku temp = detector.CheckYaku(tehai);
            if (temp != null && temp.Fan > 0)
            {
                PinfuDetector pinfu = new PinfuDetector();

            }
            else
            {

            }
            //とかやっちゃうと非常に複雑になるため、
            //デザインパターンCompositeとかChainOfResponsibility
            //あたりを使えばいいと思うよ

            //それを使ったとき

            //return new List<Yaku>(root.Detect(tehai));
            //だけでよくなるｗ


            return yakuList;
        }

        Component root;
        /// <summary>
        /// デザインパターンCompositを使ったサンプルの初期化
        /// </summary>
        public void Initialize()
        {
            root = new ChoiceOneComp();

            
            
            Component yakuman = new ChoiceOneLeaf()
            {
                YakuDetectors = new List<YakuDetector>()
                {
                    new SuankoDetector(),
                    new DaisusiDetector(),
                    new SyoususiDetector(),
                    new TsuisoDetector(),
                    new RyuisouDetector()
                    //...それ以外のヤクマンも
                }
            };

            Component notYakuman = new ChoiceAllComp();

            Component honitu = new ChoiceOneLeaf(){
                YakuDetectors = new List<YakuDetector>()
                {
                    new ChinitsuDetector(),
                    new HonitsuDetector()
                }
            };

            Component ipeiko = new ChoiceOneLeaf()
                {
                    YakuDetectors = new List<YakuDetector>()

                    {
                        new RyanpeikoDetector()
                    }//後でいーぺーこーも追加する
                };
                        
                
           
            Component yaochu = new ChoiceAllComp();
            Component notYaochu = new ChoiceAllComp();

            Component jihai = new ChoiceAllLeaf()
            {
                YakuDetectors = new List<YakuDetector>()
                {
                    //new HakuDetector(),
                    //new HatsuDetector(),など
                }
            };

            root.Add(yakuman);
            root.Add(notYakuman);

            notYakuman.Add(honitu);
            notYakuman.Add(ipeiko);

            yaochu.Add(jihai);

            /*　こんな感じのツリー構造を上記ののコードで作成している
             * グルーピングの仕方はこれがいいとは限らないので、
             * いいと思った方法でやってもらってOK
             * root -- ヤクマン --　ヤクマンいろいろ(排他)
             *      |排他
             *      -- ヤクマン以外-- ヤオチュー系 -- 字牌(両立)
             *                     |               |両立
             *                     |               --その他いろいろ
             *                     |排他
             *                     |
             *                     -- タンヤオ系　--いろいろ
             */
            
        }

    }

    public abstract class Component
    {

        public abstract IEnumerable<Yaku> Detect(AgariTehai agariTehai);
        public abstract void Add(Component comp);
        
    }
    public class ChoiceAllComp : Component
    {
        protected List<Component> components = new List<Component>();
        public override void Add(Component comp)
        {
            components.Add(comp);
        }

        public override IEnumerable<Yaku> Detect(AgariTehai agariTehai)
        {
            foreach (Component comp in components)
            {
                foreach (Yaku y in comp.Detect(agariTehai))
                {
                    if (y.Fan > 0)
                    {
                        yield return y;
                    }
                }
            }
        }
    }
    public class ChoiceOneComp : ChoiceAllComp
    {
        protected List<Component> components;

        public override IEnumerable<Yaku> Detect(AgariTehai agariTehai)
        {
            foreach (Component comp in components)
            {
                int count = 0;
                foreach (Yaku y in comp.Detect(agariTehai))
                {
                    if (y.Fan > 0)
                    {
                        count++;
                        yield return y;
                    }
                }
                if (count > 0) break;
            }
        }
    }
    public class ChoiceOneLeaf : Component
    {
        protected List<YakuDetector> detectors;

        public List<YakuDetector> YakuDetectors
        {
            get { return detectors; }
            set { detectors = value; }
        }

        public override IEnumerable<Yaku> Detect(AgariTehai agariTehai)
        {

            foreach (YakuDetector det in detectors)
            {
                Yaku y = det.CheckYaku(agariTehai);
                if (y.Fan > 0)
                {
                    yield return y;
                    break;
                }
            }

        }

        public override void Add(Component comp)
        {
            throw new NotImplementedException();
        }
    }
    public class ChoiceAllLeaf : ChoiceOneLeaf
    {
        public override IEnumerable<Yaku> Detect(AgariTehai agariTehai)
        {

            foreach (YakuDetector det in detectors)
            {
                Yaku y = det.CheckYaku(agariTehai);
                if (y.Fan > 0)
                {
                    yield return y;
                }
            }

        }
    }
    public class Leaf : Component
    {
        YakuDetector detector;

        public YakuDetector Detector
        {
            get { return detector; }
            set { detector = value; }
        }

        public override IEnumerable<Yaku> Detect(AgariTehai agariTehai)
        {
            Yaku y = detector.CheckYaku(agariTehai);
            if (y.Fan > 0)
            {
                yield return y;
            }
        }

        public override void Add(Component comp)
        {
            throw new NotImplementedException();
        }
    }

}
